package com.sms.service.impl;

import com.sms.exception.DataFileCorruptedException;
import com.sms.exception.SMSException;
import com.sms.model.Course;
import com.sms.model.Score;
import com.sms.model.Student;
import com.sms.service.ReportService;
import com.sms.service.ScoreService;
import com.sms.service.StudentService;
import com.sms.util.FileUtil;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.sms.constants.SystemConstants.*;

public class ReportServiceImpl implements ReportService {

    private final StudentService studentService;
    private final ScoreService scoreService;

    public ReportServiceImpl() {
        this.studentService = new StudentServiceImpl();
        this.scoreService = new ScoreServiceImpl();
    }

    @Override
    public Map<String, Object> generateStudentReport(String studentId) 
        throws SMSException, DataFileCorruptedException {
        
        // 获取学生基本信息
        Student student = studentService.getStudent(studentId);
        if (student == null) {
            throw new SMSException("学生不存在: " + studentId);
        }

        // 获取学生所有成绩
        List<Score> scores = scoreService.getScoresByStudent(studentId);
        
        // 计算平均分
        double average = scores.isEmpty() ? 0 : 
            scores.stream().mapToDouble(Score::getScore).average().orElse(0);

        // 构建报表数据
        Map<String, Object> report = new LinkedHashMap<>();
        report.put("studentInfo", student);
        report.put("scores", scores.stream()
            .sorted(Comparator.comparing(Score::getCourseId))
            .collect(Collectors.toList()));
        report.put("averageScore", String.format("%.2f", average));
        report.put("courseCount", scores.size());
        
        // 添加成绩分布统计
        Map<String, Long> scoreDistribution = scores.stream()
            .collect(Collectors.groupingBy(
                s -> {
                    double score = s.getScore();
                    if (score >= 90) return "优秀(90-100)";
                    if (score >= 80) return "良好(80-89)";
                    if (score >= 70) return "中等(70-79)";
                    if (score >= 60) return "及格(60-69)";
                    return "不及格(0-59)";
                },
                Collectors.counting()
            ));
        report.put("scoreDistribution", scoreDistribution);

        return report;
    }

    @Override
    public Map<String, Object> generateClassReport(String className) 
        throws DataFileCorruptedException {
        
        try {
            // 获取班级所有学生
            List<Student> students = FileUtil.loadStudents(STUDENT_FILE).stream()
                .filter(s -> s.getClassName().equals(className))
                .collect(Collectors.toList());

            if (students.isEmpty()) {
                return Collections.singletonMap("message", "班级不存在或没有学生");
            }

            // 构建班级报表数据
            Map<String, Object> report = new LinkedHashMap<>();
            report.put("className", className);
            report.put("studentCount", students.size());

            // 计算班级各科平均分
            Map<String, Double> courseAverages = new HashMap<>();
            List<Score> allScores = FileUtil.loadScores(SCORE_FILE);
            
            allScores.stream()
                .filter(s -> students.stream()
                    .anyMatch(st -> st.getId().equals(s.getStudentId())))
                .collect(Collectors.groupingBy(
                    Score::getCourseId,
                    Collectors.averagingDouble(Score::getScore)
                ))
                .forEach((courseId, avg) -> 
                    courseAverages.put(courseId, Double.parseDouble(String.format("%.2f", avg))));
            
            report.put("courseAverages", courseAverages);

            // 添加班级成绩分布
            Map<String, Long> scoreDistribution = allScores.stream()
                .filter(s -> students.stream()
                    .anyMatch(st -> st.getId().equals(s.getStudentId())))
                .collect(Collectors.groupingBy(
                    s -> {
                        double score = s.getScore();
                        if (score >= 90) return "优秀";
                        if (score >= 80) return "良好";
                        if (score >= 70) return "中等";
                        if (score >= 60) return "及格";
                        return "不及格";
                    },
                    Collectors.counting()
                ));
            report.put("scoreDistribution", scoreDistribution);

            return report;
        } catch (IOException e) {
            throw new DataFileCorruptedException("数据文件操作失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> generateCourseReport(String courseId) 
        throws SMSException, DataFileCorruptedException {
        
        // 检查课程是否存在
        Course course = getCourseById(courseId);
        if (course == null) {
            throw new SMSException("课程不存在: " + courseId);
        }

        // 获取课程所有成绩
        List<Score> scores = scoreService.getScoresByCourse(courseId);
        
        // 构建课程报表
        Map<String, Object> report = new LinkedHashMap<>();
        report.put("courseInfo", course);
        report.put("scoreCount", scores.size());
        
        if (!scores.isEmpty()) {
            // 计算统计指标
            DoubleSummaryStatistics stats = scores.stream()
                .mapToDouble(Score::getScore)
                .summaryStatistics();
            
            report.put("averageScore", String.format("%.2f", stats.getAverage()));
            report.put("maxScore", stats.getMax());
            report.put("minScore", stats.getMin());
            report.put("passRate", String.format("%.2f%%", 
                scores.stream().filter(s -> s.getScore() >= 60).count() * 100.0 / scores.size()));
            
            // 成绩分布
            Map<String, Long> distribution = scores.stream()
                .collect(Collectors.groupingBy(
                    s -> {
                        double score = s.getScore();
                        if (score >= 90) return "90-100";
                        if (score >= 80) return "80-89";
                        if (score >= 70) return "70-79";
                        if (score >= 60) return "60-69";
                        return "0-59";
                    },
                    Collectors.counting()
                ));
            report.put("scoreDistribution", distribution);
            
            // 前10名学生
            List<Map<String, Object>> topStudents = scores.stream()
                .sorted(Comparator.comparingDouble(Score::getScore).reversed())
                .limit(10)
                .map(s -> {
                    try {
                        Student student = studentService.getStudent(s.getStudentId());
                        Map<String, Object> item = new HashMap<>();
                        item.put("studentId", s.getStudentId());
                        item.put("studentName", student != null ? student.getName() : "未知");
                        item.put("score", s.getScore());
                        return item;
                    } catch (DataFileCorruptedException e) {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
            report.put("topStudents", topStudents);
        }
        
        return report;
    }

    @Override
    public Map<String, Object> generateSystemSummary() throws DataFileCorruptedException {
        try {
            Map<String, Object> summary = new LinkedHashMap<>();
            
            // 学生统计
            List<Student> students = FileUtil.loadStudents(STUDENT_FILE);
            summary.put("studentCount", students.size());
            
            // 按班级统计学生数
            Map<String, Long> classDistribution = students.stream()
                .collect(Collectors.groupingBy(
                    Student::getClassName,
                    Collectors.counting()
                ));
            summary.put("studentsByClass", classDistribution);
            
            // 课程统计
            List<Course> courses = FileUtil.loadCourses(COURSE_FILE);
            summary.put("courseCount", courses.size());
            
            // 成绩统计
            List<Score> scores = FileUtil.loadScores(SCORE_FILE);
            summary.put("scoreRecordCount", scores.size());
            
            // 整体成绩分布
            if (!scores.isEmpty()) {
                DoubleSummaryStatistics stats = scores.stream()
                    .mapToDouble(Score::getScore)
                    .summaryStatistics();
                
                summary.put("overallAverage", String.format("%.2f", stats.getAverage()));
                summary.put("highestScore", stats.getMax());
                summary.put("lowestScore", stats.getMin());
                
                Map<String, Long> scoreDistribution = scores.stream()
                    .collect(Collectors.groupingBy(
                        s -> {
                            double score = s.getScore();
                            if (score >= 90) return "优秀(90-100)";
                            if (score >= 80) return "良好(80-89)";
                            if (score >= 70) return "中等(70-79)";
                            if (score >= 60) return "及格(60-69)";
                            return "不及格(0-59)";
                        },
                        Collectors.counting()
                    ));
                summary.put("scoreDistribution", scoreDistribution);
            }
            
            return summary;
        } catch (IOException e) {
            throw new DataFileCorruptedException("数据文件操作失败: " + e.getMessage());
        }
    }

    private Course getCourseById(String courseId) throws DataFileCorruptedException {
        try {
            return FileUtil.loadCourses(COURSE_FILE).stream()
                .filter(c -> c.getCourseId().equals(courseId))
                .findFirst()
                .orElse(null);
        } catch (IOException e) {
            throw new DataFileCorruptedException("课程数据文件操作失败: " + e.getMessage());
        }
    }
}